/**
 *
 */
package hichecker.ui.custom_views.course;

import hichecker.controller.Config;
import hichecker.ui.components.custom_table.AbstractCustomTableModel;
import hichecker.ui.components.custom_table.column_class.Grade;
import hichecker.ui.components.custom_table.column_class.Points;
import hichecker.university.Course;
import hichecker.university.PTL;
import hichecker.university.PVL;
import hichecker.university.Student;

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class CourseViewTableModel extends AbstractCustomTableModel<String> {

	private Course course;
	private int FIXED_COLUMNS = 4;
	private List<Column> dynamicColumns = new ArrayList<Column>();
	private enum Column {PVL, PTL, GRADE}

	private int indexPTL;

	/**
	 *
	 */
	@SuppressWarnings("unused")
	public CourseViewTableModel(Course course) {
		super();
		this.course = course;

		for (PVL pvl : course.getPvls())
			dynamicColumns.add(Column.PVL);
		for (PTL ptl : course.getPtls())
			dynamicColumns.add(Column.PTL);
		dynamicColumns.add(Column.GRADE);

		indexPTL = course.getPvls().size();
	}

	@Override
	protected String getRowID(int row) {
		return row == getRowCount() - 1 ? null :"" + course.getParticipants().get(row).getID();
	}

	@Override
	public Object getValueAt(int row, int column) {
		// Letzt Zeile => alles leer
		if (row == getRowCount() - 1) return null;
		// Bereichsüberschreitung
		if (row >= getRowCount() || column >= getColumnCount()) return null;

		Student curStudent = course.getParticipants().get(row);
		// Standardspalte
		switch(column) {
			case 0: return curStudent.getLastName();
			case 1: return curStudent.getFirstName();
			case 2: return curStudent.getMatrikel();
			case 3: return curStudent.getStudyCourse();
			default: column -= FIXED_COLUMNS;
		}

		// Dynamische Spalten durchgehen
		if (column >= dynamicColumns.size()) return null;

		switch (dynamicColumns.get(column)) {
			case PVL:
				float check = course.getPvls().get(column).getSumPoints(curStudent);
				return check < 0 ? null : check;
			case PTL:
				check = course.getPtls().get(column - indexPTL).getGrade(curStudent);
				return check < 0 ? null : check;
			case GRADE:
				check = course.getGrade(curStudent);
				return check < 0 ? null : check;
			default: return null;
		}
	}

	@Override
	public boolean isCellEditable(int row, int column) {
		return column < FIXED_COLUMNS;
	}

	@Override
	public void setValueAt(Object value, int row, int column) {
		// Check if were at the last line. It's the case if all values are null
		boolean lastLine = row >= course.getParticipants().size();

		Student curStudent;
		if (lastLine) {
			addRow();
		}
		curStudent = course.getParticipants().get(row);

		switch (column) {
		case 0:
			curStudent.setLastName("" + value);
			break;
		case 1:
			curStudent.setFirstName("" + value);
			break;
		case 2:
			curStudent.setMatrikel("" + value);
			break;
		case 3:
			curStudent.setStudyCourse("" + value);
			break;
		}

		if (column < FIXED_COLUMNS) fireTableCellUpdated(row, column);
	}

	public void addRow() {
		course.getParticipants().add(new Student());
		fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
	}

	public void deleteRow(int row) {
		List<Student> students = course.getParticipants();
		if (row < students.size()) {
			students.remove(row);
			fireTableDataChanged();
		}
	}

	@Override
	public int getColumnCount() {
		return FIXED_COLUMNS + dynamicColumns.size();
	}

	@Override
	public int getRowCount() {
		return course.getParticipants().size() + 1;
	}

	@Override
	public Class<?> getColumnClass(int column) {
		if (column < FIXED_COLUMNS)
			return column == 2 ? Integer.class : Object.class;
		column -= FIXED_COLUMNS;
		if (column < 0 || column >= dynamicColumns.size()) return Object.class;

		switch (dynamicColumns.get(column)) {
			case PVL: return Points.class;
			case PTL: return Grade.class;
			case GRADE: return Grade.class;
			default: return Object.class;
		}
	}

	@Override
	public Object[] getHeaderValues() {
		headerValues = new Object[getColumnCount()];

		// The student data field
		headerValues[0] = Config.STUDENT_LAST_NAME;
		headerValues[1] = Config.STUDENT_FIRST_NAME;
		headerValues[2] = Config.STUDENT_MATRIKEL;
		headerValues[3] = Config.STUDENT_STUDY_COURSE;

		// The requirements
		for (int i = 0; i < course.getRequirements().size(); i++) {
			headerValues[i+4] = course.getRequirements().get(i).getName();
		}

		// The modulgrade at last
		headerValues[getColumnCount() - 1] = Config.COURSE_GRADE;

		return headerValues;
	}

}
